package pl.nazaweb.jboot.afk;

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.security.MessageDigest;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author Marek Kawczyński
 */
public class ScreanCaptureWatcher extends Thread {

    public static String IMAGE_EXTENSION = "png";
    private Rectangle captureSpace;
    private Robot robot;
    public long interval = 500;
    private String lastHash;
    private String newHash;
    private boolean isExecuting = false;
    private ICallback callback;

    public ScreanCaptureWatcher(Rectangle captureSpace, ICallback callback) throws AWTException {
        this.callback = callback;
        this.captureSpace = captureSpace;
        robot = new Robot();
    }

    @Override
    public void run() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            System.err.println(ex.getMessage());
        }
        while (true) {
            try {
                Thread.sleep(interval);
                if (isExecuting == false) {
                    isExecuting = true;
                    capture();
                    isExecuting = false;
                }
            } catch (Exception ex) {
                System.err.println(ex.getMessage());
            }

        }
    }

    private void capture() {
        try {
            //File tempFile = File.createTempFile("screenshot", "." + IMAGE_EXTENSION);
            BufferedImage bufferedImage = robot.createScreenCapture(captureSpace);
            //ImageIO.write(bufferedImage, IMAGE_EXTENSION, tempFile);
            setHash(bufferedImage);
            //tempFile.delete();
            executeCallback();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

    private void executeCallback() {
        if (lastHash == null && newHash == null) {
            return;
        }
        if (lastHash.equals(newHash)) {
        } else {
            callback.execute();
            System.out.println("callback will execute");
        }
        lastHash = newHash;
    }

    private String getMd5HashOfCapturedImage(BufferedImage image) {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            ImageIO.write(image, IMAGE_EXTENSION, outputStream);
            byte[] data = outputStream.toByteArray();
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(data);
            byte[] hash = md.digest();
            return returnHex(hash);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return null;
    }

    private String returnHex(byte[] inBytes) throws Exception {
        String hexString = null;
        for (int i = 0; i < inBytes.length; i++) {
            hexString += Integer.toString((inBytes[i] & 0xff) + 0x100, 16).substring(1);
        }
        return hexString;
    }

    public long getInterval() {
        return interval;
    }

    public void setInterval(long interval) {
        this.interval = interval;
    }

    public void setHash(BufferedImage image) {
        String hash = getMd5HashOfCapturedImage(image);
        if (lastHash == null) {
            lastHash = hash;
        }
        newHash = hash;
    }
}
